package General;
import java.util.LinkedList;
import java.util.Iterator;
import java.util.Arrays;
import java.util.List;
import java.util.Collections;
import Card.*;


import Card.Card;

// Norse = 0
// Egyptian = 1
// Greek = 2

//In the interests of time and simplicity Culture will house data on build costs, 
public class Culture {
	
	private static Card[][] RandomCardSet= new Card [3][46];
	public static void initializeCard()
	{
		//NORSE
		RandomCardSet[0][1]= new AgeCard (null, true);
		RandomCardSet[0][2]= new AgeCard (null, true);
		RandomCardSet[0][3]= new AgeCard (null, true);
		RandomCardSet[0][4]= new AgeCard (null/*ODIN THE ALLSEER*/, true);
		
		RandomCardSet[0][5]= new AttackCard(null,5);
		RandomCardSet[0][6]= new AttackCard(null,5);
		RandomCardSet[0][7]= new AttackCard(null,6);
		RandomCardSet[0][8]= new AttackCard(null,7);
		RandomCardSet[0][9]= new AttackCard(null,7);
		RandomCardSet[0][10]= new AttackCard(null /*TYR*/,6);
		RandomCardSet[0][11]= new AttackCard(null/*BRAGI*/,6);
		
		RandomCardSet[0][12]= new BuildCard(null,4);
		RandomCardSet[0][13]= new BuildCard(null,3);
		RandomCardSet[0][14]= new BuildCard(null,2);
		RandomCardSet[0][15]= new BuildCard(null,3);
		RandomCardSet[0][16]= new BuildCard(null,3);
		RandomCardSet[0][17]= new BuildCard(null,2);
		RandomCardSet[0][18]= new BuildCard(null/*NJORD*/,4);
		
		RandomCardSet[0][19]= new ExploreCard(null,2);
		RandomCardSet[0][20]= new ExploreCard(null,1);
		RandomCardSet[0][21]= new ExploreCard(null,0);
		RandomCardSet[0][22]= new ExploreCard(null,0);
		RandomCardSet[0][23]= new ExploreCard(null,2);
		RandomCardSet[0][24]= new ExploreCard(null/*BALDR*/,0);
		
		RandomCardSet[0][25]= new GatherCard (null, true);
		RandomCardSet[0][26]= new GatherCard (null, true);
		RandomCardSet[0][27]= new GatherCard (null, true);
		RandomCardSet[0][28]= new GatherCard (null, true);
		RandomCardSet[0][29]= new GatherCard (null, true);
		RandomCardSet[0][30]= new GatherCard (null, true/*FREYJA*/);
		RandomCardSet[0][31]= new GatherCard (null, true/*THOR*/);
		RandomCardSet[0][32]= new GatherCard (null, true)/*SKADI*/;
		
		RandomCardSet[0][34]= new RecruitCard (null, 5);
		RandomCardSet[0][35]= new RecruitCard (null, 4);
		RandomCardSet[0][36]= new RecruitCard (null, 4);
		RandomCardSet[0][37]= new RecruitCard (null, 3);
		RandomCardSet[0][38]= new RecruitCard (null, 5);
		RandomCardSet[0][39]= new RecruitCard (null, 3);
		RandomCardSet[0][40]= new RecruitCard (null/*HEL*/, 3);
		
		RandomCardSet[0][41]= new TradeCard (null,1);
		RandomCardSet[0][42]= new TradeCard (null,1);
		RandomCardSet[0][43]= new TradeCard (null,1);
		RandomCardSet[0][44]= new TradeCard (null,1);
		RandomCardSet[0][45]= new TradeCard (null/*FORSETI*/,0);
		RandomCardSet[0][00]= new TradeCard (null/*LOKI*/,0);
	
		//EGYPTIAN
		RandomCardSet[1][1]= new AgeCard (null, true);
		RandomCardSet[1][2]= new AgeCard (null, true);
		RandomCardSet[1][3]= new AgeCard (null/*HATHOR*/, true);
		RandomCardSet[1][4]= new AgeCard (null/*SET*/, true);
		
		RandomCardSet[1][5]= new AttackCard(null,5);
		RandomCardSet[1][6]= new AttackCard(null,6);
		RandomCardSet[1][7]= new AttackCard(null,5);
		RandomCardSet[1][8]= new AttackCard(null,7);
		RandomCardSet[1][9]= new AttackCard(null,6);
		RandomCardSet[1][10]= new AttackCard(null/*ISIS*/,7);
		RandomCardSet[1][11]= new AttackCard(null /*SEKHMET*/,6);
		RandomCardSet[1][12]= new AttackCard(null/*THOTH*/,6);
		
		RandomCardSet[1][13]= new BuildCard(null,4);
		RandomCardSet[1][14]= new BuildCard(null,3);
		RandomCardSet[1][15]= new BuildCard(null,2);
		RandomCardSet[1][16]= new BuildCard(null,3);
		RandomCardSet[1][17]= new BuildCard(null,2);
		RandomCardSet[1][18]= new BuildCard(null/*NEPTHYS*/,3);
		RandomCardSet[1][19]= new BuildCard(null/*HORUS*/,3);
		
		RandomCardSet[1][20]= new ExploreCard(null,2);
		RandomCardSet[1][21]= new ExploreCard(null,0);
		RandomCardSet[1][22]= new ExploreCard(null,0);
		RandomCardSet[1][23]= new ExploreCard(null,2);
		RandomCardSet[1][24]= new ExploreCard(null/*PTAH*/,2);
		
		RandomCardSet[1][25]= new GatherCard (null, true);
		RandomCardSet[1][26]= new GatherCard (null, true);
		RandomCardSet[1][27]= new GatherCard (null, true);
		RandomCardSet[1][28]= new GatherCard (null, true);
		RandomCardSet[1][29]= new GatherCard (null, true);
		RandomCardSet[1][30]= new GatherCard (null, true);
		RandomCardSet[1][31]= new GatherCard (null, true);
		RandomCardSet[1][32]= new GatherCard (null, true)/*RA*/;
	
		RandomCardSet[1][34]= new RecruitCard (null, 5);
		RandomCardSet[1][35]= new RecruitCard (null, 3);
		RandomCardSet[1][36]= new RecruitCard (null, 4);
		RandomCardSet[1][37]= new RecruitCard (null, 3);
		RandomCardSet[1][38]= new RecruitCard (null, 4);
		RandomCardSet[1][39]= new RecruitCard (null/*BAST*/, 6);
		RandomCardSet[1][40]= new RecruitCard (null/*ANUBIS*/, 4);
	
		RandomCardSet[1][41]= new TradeCard (null,1);
		RandomCardSet[1][42]= new TradeCard (null,1);
		RandomCardSet[1][43]= new TradeCard (null,1);
		RandomCardSet[1][44]= new TradeCard (null,1);
		RandomCardSet[1][45]= new TradeCard (null,1);
		RandomCardSet[1][00]= new TradeCard (null,1);
		
		//GREEK
		RandomCardSet[2][1]= new AgeCard (null, true);
		RandomCardSet[2][2]= new AgeCard (null, true);
		RandomCardSet[2][3]= new AgeCard (null/*HEPHAESTOS*/, true);
		RandomCardSet[2][4]= new AgeCard (null/*ZEUS*/, true);
		
		RandomCardSet[2][5]= new AttackCard(null,6);
		RandomCardSet[2][6]= new AttackCard(null,6);
		RandomCardSet[2][7]= new AttackCard(null,6);
		RandomCardSet[2][8]= new AttackCard(null,5);
		RandomCardSet[2][9]= new AttackCard(null,5);
		RandomCardSet[2][10]= new AttackCard(null,7);
		RandomCardSet[2][11]= new AttackCard(null,7);
		RandomCardSet[2][12]= new AttackCard(null/*APHRODITE*/,6);
		
		RandomCardSet[2][13]= new BuildCard(null,2);
		RandomCardSet[2][14]= new BuildCard(null,3);
		RandomCardSet[2][15]= new BuildCard(null,3);
		RandomCardSet[2][16]= new BuildCard(null,3);
		RandomCardSet[2][17]= new BuildCard(null,4);
		RandomCardSet[2][18]= new BuildCard(null,2);
		RandomCardSet[2][19]= new BuildCard(null/*HERA*/,3);
		
		RandomCardSet[2][20]= new ExploreCard(null,2);
		RandomCardSet[2][21]= new ExploreCard(null,2);
		RandomCardSet[2][22]= new ExploreCard(null,0);
		RandomCardSet[2][23]= new ExploreCard(null,0);
		RandomCardSet[2][24]= new ExploreCard(null/*ARTEMIS*/,2);
		
		RandomCardSet[2][25]= new GatherCard (null, true);
		RandomCardSet[2][26]= new GatherCard (null, true);
		RandomCardSet[2][27]= new GatherCard (null, true);
		RandomCardSet[2][28]= new GatherCard (null, true);
		RandomCardSet[2][29]= new GatherCard (null, true);
		RandomCardSet[2][30]= new GatherCard (null, true)/*POSEIDON*/;
		RandomCardSet[2][31]= new GatherCard (null, true)/*HADES*/;
		RandomCardSet[2][32]= new GatherCard (null, true)/*DIONYSUS*/;
	
		RandomCardSet[2][34]= new RecruitCard (null, 3);
		RandomCardSet[2][35]= new RecruitCard (null, 5);
		RandomCardSet[2][36]= new RecruitCard (null, 3);
		RandomCardSet[2][37]= new RecruitCard (null, 5);
		RandomCardSet[2][38]= new RecruitCard (null, 4);
		RandomCardSet[2][39]= new RecruitCard (null, 4);
		RandomCardSet[2][40]= new RecruitCard (null/*APOLLO*/, 4);
	
		RandomCardSet[2][41]= new TradeCard (null,1);
		RandomCardSet[2][42]= new TradeCard (null,1);
		RandomCardSet[2][43]= new TradeCard (null,1);
		RandomCardSet[2][44]= new TradeCard (null,1);
		RandomCardSet[2][45]= new TradeCard (null,1);
		RandomCardSet[2][00]= new TradeCard (null/*HERMES*/,0);
	
	
	
	};
			
	private static Card[] permanentCardSet = 
	{
		new AgeCard(null, false), new AttackCard(null, 4), new BuildCard(null, 1), 
		new ExploreCard(null,1), new GatherCard(null, false), new RecruitCard(null,2),
		new TradeCard(null, 2)
	};
	
	private static Tile[] tileSet={
		new Tile (new Resource (2,0,0,0,0),  Terrain.FERTILE), new Tile (new Resource (2,0,0,0,0),  Terrain.FERTILE), 
		new Tile (new Resource (2,0,0,0,0),  Terrain.FERTILE), new Tile (new Resource (2,0,0,0,0),  Terrain.FERTILE), 
		new Tile (new Resource (2,0,0,0,0),  Terrain.FERTILE), new Tile (new Resource (2,0,0,0,0),  Terrain.FERTILE), 
		new Tile (new Resource (2,0,0,0,0),  Terrain.FERTILE), new Tile (new Resource (2,0,0,0,0),  Terrain.FERTILE), 
		new Tile (new Resource (2,0,0,0,0),  Terrain.FERTILE), new Tile (new Resource (2,0,0,0,0),  Terrain.FERTILE), 
		new Tile (new Resource (2,0,0,0,0),  Terrain.FERTILE), new Tile (new Resource (2,0,0,0,0),  Terrain.FERTILE),
		
		new Tile (new Resource (0,1,0,0,0), Terrain.FERTILE), new Tile (new Resource (0,1,0,0,0), Terrain.FERTILE),
		new Tile (new Resource (0,1,0,0,0), Terrain.FERTILE), 
		
		new Tile (new Resource (0,0,1,0,0), Terrain.FERTILE),
		new Tile (new Resource (0,0,1,0,0), Terrain.FERTILE), new Tile (new Resource (0,0,1,0,0), Terrain.FERTILE),
		
		new Tile (new Resource (0,0,0,1,0), Terrain.FERTILE), new Tile (new Resource (0,0,0,1,0), Terrain.FERTILE),
		new Tile (new Resource (0,0,0,1,0), Terrain.FERTILE),
		
		new Tile (new Resource (0,2,0,0,0), Terrain.FOREST),
		new Tile (new Resource (0,2,0,0,0), Terrain.FOREST), new Tile (new Resource (0,2,0,0,0), Terrain.FOREST),
		new Tile (new Resource (0,2,0,0,0), Terrain.FOREST), new Tile (new Resource (0,2,0,0,0), Terrain.FOREST),
		new Tile (new Resource (0,2,0,0,0), Terrain.FOREST), new Tile (new Resource (0,2,0,0,0), Terrain.FOREST),
		new Tile (new Resource (0,2,0,0,0), Terrain.FOREST), new Tile (new Resource (0,2,0,0,0), Terrain.FOREST),
		
		new Tile (new Resource (1,0,0,0,0), Terrain.FOREST), new Tile (new Resource (1,0,0,0,0), Terrain.FOREST),
		
		new Tile (new Resource (0,0,0,1,0), Terrain.FOREST), new Tile (new Resource (0,0,0,1,0), Terrain.FOREST),
		
		new Tile (new Resource (0,0,1,0,0), Terrain.FOREST), new Tile (new Resource (0,0,1,0,0), Terrain.FOREST),
		
		new Tile (new Resource (0,0,0,2,0), Terrain.HILL), new Tile (new Resource (0,0,0,2,0), Terrain.HILL),
		new Tile (new Resource (0,0,0,2,0), Terrain.HILL), new Tile (new Resource (0,0,0,2,0), Terrain.HILL),
		
		new Tile  (new Resource (1,0,0,0,0), Terrain.HILL), new Tile  (new Resource (1,0,0,0,0), Terrain.HILL),
		new Tile  (new Resource (1,0,0,0,0), Terrain.HILL), new Tile  (new Resource (1,0,0,0,0), Terrain.HILL),
		
		new Tile (new Resource (0,1,0,0,0), Terrain.HILL), new Tile (new Resource (0,1,0,0,0), Terrain.HILL),
		new Tile (new Resource (0,1,0,0,0), Terrain.HILL), new Tile (new Resource (0,1,0,0,0), Terrain.HILL),
		
		new Tile (new Resource (0,0,1,0,0), Terrain.HILL), new Tile (new Resource (0,0,1,0,0), Terrain.HILL),
		new Tile (new Resource (0,0,1,0,0), Terrain.HILL), new Tile (new Resource (0,0,1,0,0), Terrain.HILL),
		
		new Tile (new Resource (0,0,0,2,0), Terrain.MOUNTAIN), new Tile (new Resource (0,0,0,2,0), Terrain.MOUNTAIN),
		new Tile (new Resource (0,0,0,2,0), Terrain.MOUNTAIN), new Tile (new Resource (0,0,0,2,0), Terrain.MOUNTAIN),
		new Tile (new Resource (0,0,0,2,0), Terrain.MOUNTAIN), new Tile (new Resource (0,0,0,2,0), Terrain.MOUNTAIN),
		
		new Tile (new Resource (0,1,0,0,0), Terrain.MOUNTAIN), new Tile (new Resource (0,1,0,0,0), Terrain.MOUNTAIN),
		new Tile (new Resource (0,1,0,0,0), Terrain.MOUNTAIN),
		
		new Tile (new Resource (0,0,1,0,0), Terrain.MOUNTAIN), new Tile (new Resource (0,0,1,0,0), Terrain.MOUNTAIN),
		new Tile (new Resource (0,0,1,0,0), Terrain.MOUNTAIN),
		
		new Tile (new Resource (0,0,2,0,0), Terrain.DESERT), new Tile (new Resource (0,0,2,0,0), Terrain.DESERT),
		new Tile (new Resource (0,0,2,0,0), Terrain.DESERT), new Tile (new Resource (0,0,2,0,0), Terrain.DESERT),
		new Tile (new Resource (0,0,2,0,0), Terrain.DESERT), new Tile (new Resource (0,0,2,0,0), Terrain.DESERT),
		new Tile (new Resource (0,0,2,0,0), Terrain.DESERT),
		
		
		new Tile (new Resource (0,0,0,1,0), Terrain.DESERT), new Tile (new Resource (0,0,0,1,0), Terrain.DESERT),
		new Tile (new Resource (0,0,0,1,0), Terrain.DESERT), new Tile (new Resource (0,0,0,1,0), Terrain.DESERT),
		new Tile (new Resource (0,0,0,1,0), Terrain.DESERT), new Tile (new Resource (0,0,0,1,0), Terrain.DESERT),
		new Tile (new Resource (0,0,0,1,0), Terrain.DESERT),
		
		
		new Tile (new Resource (0,1,0,0,0), Terrain.SWAMP), new Tile (new Resource (0,1,0,0,0), Terrain.SWAMP), 
		new Tile (new Resource (0,1,0,0,0), Terrain.SWAMP), new Tile (new Resource (0,1,0,0,0), Terrain.SWAMP), 
		
		new Tile (new Resource (1,0,0,0,0), Terrain.SWAMP), new Tile (new Resource (1,0,0,0,0), Terrain.SWAMP),
		new Tile (new Resource (1,0,0,0,0), Terrain.SWAMP), new Tile (new Resource (1,0,0,0,0), Terrain.SWAMP),
		
		new Tile (new Resource (0,0,1,0,0), Terrain.SWAMP), new Tile (new Resource (0,0,1,0,0), Terrain.SWAMP),
		new Tile (new Resource (0,0,1,0,0), Terrain.SWAMP), new Tile (new Resource (0,0,1,0,0), Terrain.SWAMP)
		
	};
	/**
	 * Returns an array of squares corresponding to the inputed culture 
	 * @param culture
	 */
	public static Square[][] getSquare(int culture){
		switch(culture){
		case 0:
			//set up Norse resource gathering Area
			Square[][]norseResourceGatheringArea= new Square [4][4];
			norseResourceGatheringArea [0][0]= new Square (Terrain.FERTILE);
			norseResourceGatheringArea [0][1]= new Square (Terrain.MOUNTAIN);
			norseResourceGatheringArea [0][2]= new Square (Terrain.MOUNTAIN);
			norseResourceGatheringArea [0][3]= new Square (Terrain.MOUNTAIN);
			norseResourceGatheringArea [1][0]= new Square (Terrain.FERTILE);
			norseResourceGatheringArea [1][1]= new Square (Terrain.FOREST);
			norseResourceGatheringArea [1][2]= new Square (Terrain.HILL);
			norseResourceGatheringArea [1][3]= new Square (Terrain.MOUNTAIN);
			norseResourceGatheringArea [2][0]= new Square (Terrain.HILL);
			norseResourceGatheringArea [2][1]= new Square (Terrain.SWAMP);
			norseResourceGatheringArea [2][2]= new Square (Terrain.FOREST);
			norseResourceGatheringArea [2][3]= new Square (Terrain.HILL);
			norseResourceGatheringArea [3][0]= new Square (Terrain.DESERT);
			norseResourceGatheringArea [3][1]= new Square (Terrain.FOREST);
			norseResourceGatheringArea [3][2]= new Square (Terrain.FOREST);
			norseResourceGatheringArea [3][3]= new Square (Terrain.FERTILE);
			return norseResourceGatheringArea;
		case 1:
			//set up Egyptian Resource Gathering Area
			Square[][] egyptianResourceGatheringArea= new Square[4][4];
			egyptianResourceGatheringArea [0][0]= new Square (Terrain.DESERT);
			egyptianResourceGatheringArea [0][1]= new Square (Terrain.DESERT);
			egyptianResourceGatheringArea [0][2]= new Square (Terrain.SWAMP);
			egyptianResourceGatheringArea [0][3]= new Square (Terrain.SWAMP);
			egyptianResourceGatheringArea [1][0]= new Square (Terrain.FOREST);
			egyptianResourceGatheringArea [1][1]= new Square (Terrain.DESERT);
			egyptianResourceGatheringArea [1][2]= new Square (Terrain.FERTILE);
			egyptianResourceGatheringArea [1][3]= new Square (Terrain.FERTILE);
			egyptianResourceGatheringArea [2][0]= new Square (Terrain.DESERT);
			egyptianResourceGatheringArea [2][1]= new Square (Terrain.DESERT);
			egyptianResourceGatheringArea [2][2]= new Square (Terrain.FERTILE);
			egyptianResourceGatheringArea [2][3]= new Square (Terrain.FERTILE);
			egyptianResourceGatheringArea [3][0]= new Square (Terrain.DESERT);
			egyptianResourceGatheringArea [3][1]= new Square (Terrain.HILL);
			egyptianResourceGatheringArea [3][2]= new Square (Terrain.FERTILE);
			egyptianResourceGatheringArea [3][3]= new Square (Terrain.HILL);
			return egyptianResourceGatheringArea;
		case 2:
			//set up Greek Resource Gathering Area
			Square[][] greekResourceGatheringArea= new Square [4][4];
			greekResourceGatheringArea [0][0]= new Square (Terrain.FERTILE);
			greekResourceGatheringArea [0][1]= new Square (Terrain.FERTILE);
			greekResourceGatheringArea [0][2]= new Square (Terrain.FOREST);
			greekResourceGatheringArea [0][3]= new Square (Terrain.SWAMP);
			greekResourceGatheringArea [1][0]= new Square (Terrain.HILL);
			greekResourceGatheringArea [1][1]= new Square (Terrain.MOUNTAIN);
			greekResourceGatheringArea [1][2]= new Square (Terrain.FERTILE);
			greekResourceGatheringArea [1][3]= new Square (Terrain.FERTILE);
			greekResourceGatheringArea [2][0]= new Square (Terrain.HILL);
			greekResourceGatheringArea [2][1]= new Square (Terrain.HILL);
			greekResourceGatheringArea [2][2]= new Square (Terrain.HILL);
			greekResourceGatheringArea [2][3]= new Square (Terrain.HILL);
			greekResourceGatheringArea [3][0]= new Square (Terrain.DESERT);
			greekResourceGatheringArea [3][1]= new Square (Terrain.HILL);
			greekResourceGatheringArea [3][2]= new Square (Terrain.HILL);
			greekResourceGatheringArea [3][3]= new Square (Terrain.HILL);
			return greekResourceGatheringArea;
			default:
				throw new IllegalArgumentException("Specified culture does not exist");
		}
	}
	static Tile[][] resourceProductionArea;
	static General.Resource[] buildCosts;  //antiquated prices baked into the Buildings themselves at the moment
		// Norse = 0
		// Egyptian = 1
		// Greek = 2
		//Some sort of data storage, doesn't have to be exactly this
		//Alternative 3 separate linked lists
//		buildCosts = {};	//3xN array.  Index corresponds to buildingID
//		randomCardSet={}; 		//3xN.  Corresponds to cardID?
//		battleCardSet={};		//Are the battle cards different per culture?
		
		//Alternatively make a bunch of static Collections
	private Culture(){	//this is going to be all implemented statically, never instantiated;
	}
	public static Deck getRandom(int culture){
		LinkedList<Card> out = new LinkedList<Card>(Arrays.asList(RandomCardSet[culture]));
		Collections.shuffle(out);
		return new Deck(out);
	}
//	public static Deck getBattle(int i){
//		LinkedList<Card> out = new LinkedList<Card>(Arrays.asList(battleCardSet[i]));
//		Collections.shuffle(out);
//		return new Deck(out);
//	}
	public static Card[] getPermanent(){
		return permanentCardSet;
	}
	public static LinkedList<Tile> getTileSet(){
		LinkedList<Tile> out =new LinkedList<Tile>(Arrays.asList(tileSet));
		Collections.shuffle(out);
		return out;
	}

}
